package com.mic.controller;

import com.mic.mapper.Oauth2RegisteredClientMapper;
import com.mic.repository.SelfJdbcRegisteredClientRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@RestController
public class InsertController {

    @Autowired
    RegisteredClientRepository registeredClientRepository;

    @GetMapping("/insert")
    public void insert(){
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        RegisteredClient registeredClient = RegisteredClient.withId("d07addb0-1790-4c09-a34a-903e4e5885e8")
                .clientId("oidc-client")
                .clientName("oidc-client")
                //不配置PasswordEncoder，密文前边需要添加前缀{bcrypt}，表明使用的加密方式，
                // 配置了以后无需添加前坠，自动使用你配置的实现类进行解密匹配
                .clientSecret("{bcrypt}"+ encoder.encode("secret"))
                .clientAuthenticationMethods(s -> {
                    s.add(ClientAuthenticationMethod.CLIENT_SECRET_POST);
                    s.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
                })
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                .redirectUri("http://localhost:8080/login/oauth2/code/oidc-client")
                .scope("message.read")
                .clientSettings(ClientSettings.builder()
                        .requireAuthorizationConsent(true)
                        .requireProofKey(false)
                        .build())
                .tokenSettings(TokenSettings.builder()
                        .idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
                        .accessTokenTimeToLive(Duration.ofSeconds(30 * 60))
                        .refreshTokenTimeToLive(Duration.ofSeconds(60 * 60))
                        .reuseRefreshTokens(true)
                        .build())
                .build();
        registeredClientRepository.save(registeredClient);
        System.out.println(registeredClient);
    }

    @GetMapping("/save")
    public void save(){
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        RegisteredClient client = RegisteredClient
                .withId(UUID.randomUUID().toString())
                .clientId("oidc-client")
                .clientSecret("{bcrypt}"+ encoder.encode("secret"))
                .clientName("oidc-client")
                .clientAuthenticationMethods(methods -> methods.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC))
                .authorizationGrantTypes(types -> {
                    types.add(AuthorizationGrantType.AUTHORIZATION_CODE);
                    types.add(AuthorizationGrantType.REFRESH_TOKEN);
                })
                .redirectUri("http://localhost:8080/login/oauth2/code/oidc-client")
                .postLogoutRedirectUri("http://localhost:8080/")
                .scopes(scopes -> {
                    scopes.add(OidcScopes.OPENID);
                    scopes.add(OidcScopes.PROFILE);
                })
                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
                .tokenSettings(TokenSettings.builder().build())
                .build();

        registeredClientRepository.save(client);
        System.out.println(client);
    }
}
